<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>LoLLMs Endpoint Test</title>
    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
    <style>
        .hover\:bg-blue-600:hover {
            background-color: #2563eb;
        }

        .active\:bg-blue-700:active {
            background-color: #1d4ed8;
        }
    </style>
</head>

<body class="bg-gray-100 w-full">
    <div class="flex items-center justify-center min-h-screen w-full">
        <div class="w-full bg-blue-300 p-6 rounded shadow m-4">
            <h1 class="text-2xl font-bold mb-4">LoLLMs Playground</h1>
            <div id="connection-section">
                <div class="mb-4">
                    <label for="host" class="block text-sm font-medium text-gray-700">Host:</label>
                    <input id="host" type="text" class="mt-1 p-2 border border-gray-300 rounded-md w-full"
                        value="localhost" />
                </div>
                <div class="mb-4">
                    <label for="port" class="block text-sm font-medium text-gray-700">Port:</label>
                    <input id="port" type="number" class="mt-1 p-2 border border-gray-300 rounded-md w-full" value="9600" />
                </div>
                <button id="connect-btn"
                    class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700 text-white font-bold py-2 px-4 rounded">Connect</button>
                <label class="hidden" id = "connecting">connecting ...</label>
            </div>
            <div id="generation-section" class="hidden w-full">
                <div>
                    <button id="generate-btn"
                    class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700 text-white font-bold py-2 px-4 rounded">Generate
                    Text</button>
                </div>
                <div>
                    <button id="stop-btn"
                    class="bg-red-500 hover:bg-red-600 active:bg-red-700 text-white font-bold py-2 px-4 rounded hidden">Stop
                    Generation</button>
                </div>
                <div>
                    <textarea  id="text" class="mt-4 p-2 border border-gray-300 rounded-md h-64 overflow-y-scroll w-full" type="text"></textarea>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.socket.io/4.4.1/socket.io.min.js"></script>
    <script>
        const socket = io();
        const connectButton = document.getElementById('connect-btn');
        const generateButton = document.getElementById('generate-btn');
        const stopButton = document.getElementById('stop-btn');
        const connectionSection = document.getElementById('connection-section');
        const generationSection = document.getElementById('generation-section');
        const connectingText = document.getElementById('connecting');

        // Append the received chunks to the text div
        function appendToOutput(chunk) {
            const outputDiv = document.getElementById('text');
            outputDiv.value += chunk;
            outputDiv.scrollTop = outputDiv.scrollHeight;
        }

        // Event handler for receiving generated text chunks
        socket.on('text_chunk', data => {
            console.log('Received chunk:', data.chunk);
            appendToOutput(data.chunk);
        });

        // Event handler for receiving generated text chunks
        socket.on('text_generated', data => {
            console.log('text generated:', data.text);
            // Toggle button visibility
            generateButton.classList.remove('hidden');
            stopButton.classList.add('hidden');
        });

        // Event handler for successful connection
        socket.on('connect', () => {
            console.log('Connected to LoLLMs server');
            connectButton.disabled = true;
            connectingText.classList.add("hidden")
            connectionSection.classList.add('hidden');
            generationSection.classList.remove('hidden');
        });

        // Event handler for error during text generation
        socket.on('buzzy', error => {
            console.error('Server is busy. Wait for your turn', error);
            const outputDiv = document.getElementById('text');
            outputDiv.value += `<p class="text-red-500">Error: ${error.message}</p>`;
            outputDiv.scrollTop = outputDiv.scrollHeight;
            // Toggle button visibility
            generateButton.classList.remove('hidden');
            stopButton.classList.add('hidden');

        });

        // Event handler for error during text generation
        socket.on('generation_canceled', error => {
            // Toggle button visibility
            generateButton.classList.remove('hidden');
            stopButton.classList.add('hidden');

        });

        

        // Triggered when the "Connect" button is clicked
        connectButton.addEventListener('click', () => {
            const hostInput = document.getElementById('host');
            const portInput = document.getElementById('port');
            const host = hostInput.value.trim();
            const port = parseInt(portInput.value);

            if (host && port) {
                socket.io.uri = `http://${host}:${port}`;
                socket.connect();
                connectingText.classList.remove("hidden")
            }
        });

        // Triggered when the "Generate Text" button is clicked
        generateButton.addEventListener('click', () => {
            const outputDiv = document.getElementById('text');
            var prompt = outputDiv.value
            console.log(prompt)
            // Trigger the 'generate_text' event with the prompt
            socket.emit('generate_text', { prompt, personality: -1, n_predicts: 1024 });

            // Toggle button visibility
            generateButton.classList.add('hidden');
            stopButton.classList.remove('hidden');
        });

        // Triggered when the "Stop Generation" button is clicked
        stopButton.addEventListener('click', () => {
            // Trigger the 'cancel_generation' event
            socket.emit('cancel_generation',{});

        });
    </script>
</body>

</html>
